; ----------------------------------------------------------------
; This file is released under the GPL v3 License
; Copyleft (k) 2008
; by Jose Rodriguez-Rosa (a.k.a. Boriel) <http://www.boriel.com>
; Use this file as a template to develop your own library file
; ----------------------------------------------------------------
; Emulates both memmove and memcpy C routines
; Blocks will safely copies if they overlap
; HL => Start of source block
; DE => Start of destiny block
; BC => Block length
;
__MEMCPY:
               ;- PROC
               ;- LOCAL __MEMCPY2
lda z80_l      ;- push hl
pha
lda z80_h
pha
               ;- add hl,bc
ora z80_a      ;- or a
               ;- sbc hl,de  ; checks if DE > HL + BC
pla            ;- pop hl  ; recovers HL. If Carry set => DE > HL
sta z80_h
pla
sta z80_l
               ;- jr c, __MEMCPY2
               ;- ; Now checks if DE <= HL
               ;- sbc hl,de
               ;- add hl,de
               ;- jr nc, __MEMCPY2
               ;- dec bc
lda z80_l      ;- add hl,bc
clc
adc z80_c
sta z80_l
lda z80_h
adc z80_b
sta z80_h
lda z80_e      ;- ex de,hl
ldx z80_l
stx z80_e
sta z80_l
lda z80_d
ldx z80_h
stx z80_d
sta z80_h
lda z80_l      ;- add hl,bc
clc
adc z80_c
sta z80_l
lda z80_h
adc z80_b
sta z80_h
lda z80_e      ;- ex de,hl
ldx z80_l
stx z80_e
sta z80_l
lda z80_d
ldx z80_h
stx z80_d
sta z80_h
inc z80_c      ;- inc bc      ; HL and DE point to the last byte position
bne *+4
inc z80_b
               ;- lddr        ; Copies from end to beginning
rts            ;- ret
__MEMCPY2:
ldy #$00             ;- ldir
ldx z80_b
beq ldir_last_page
ldir_loop:
lda (z80_hl),y
sta (z80_de),y
iny
bne ldir_loop
inc z80_h
inc z80_d
dex
bne ldir_loop
ldir_last_page:
lda z80_c
beq ldir_end
ldir_last_page_loop:
lda (z80_hl),y
sta (z80_de),y
iny
cpy z80_c
bne ldir_last_page_loop
ldir_end:
stx z80_c
stx z80_b
tya
clc
adc z80_l
sta z80_l
bcc *+4
inc z80_h
tya
clc
adc z80_e
sta z80_e
bcc *+4
inc z80_d
rts            ;- ret
               ;- ENDP
